package org.starsource.forum.server.web;

import java.util.LinkedHashSet;
import java.util.Iterator;
import java.util.Set;

import org.starsource.forum.client.domain.CategoryObject;
import org.starsource.forum.client.domain.MessageObject;
import org.starsource.forum.client.domain.SessionObject;
import org.starsource.forum.client.exception.CategoryNotFoundException;
import org.starsource.forum.client.exception.DatabaseException;
import org.starsource.forum.client.exception.MessageNotFoundException;
import org.starsource.forum.client.exception.PermissionDeniedException;
import org.starsource.forum.client.exception.ResourceNotFoundException;
import org.starsource.forum.client.exception.SessionNotFoundException;
import org.starsource.forum.client.web.ForumService;
import org.starsource.forum.server.domain.Category;
import org.starsource.forum.server.domain.Message;
import org.starsource.forum.server.domain.Resource;
import org.starsource.forum.server.domain.Session;
import org.starsource.forum.server.domain.User;
import org.starsource.forum.server.transaction.CategoryTransaction;
import org.starsource.forum.server.transaction.MessengerTransaction;

/**
 * The server side implementation of the RPC service.
 */
public class ForumServiceImpl extends SpringRemoteServiceServlet implements ForumService {

//	private static org.apache.log4j.Logger logger = org.apache.log4j.LogManager
//	.getLogger(ForumServiceImpl.class.getName());

	private static final long serialVersionUID = 4959112059617939806L;

	private MessengerTransaction forumTransaction;

	public MessengerTransaction getForumTransaction() {
		return this.forumTransaction;
	}

	public void setForumTransaction(MessengerTransaction forumTransaction) {
		this.forumTransaction = forumTransaction;
	}

	private CategoryTransaction categoryTransaction;

	public CategoryTransaction getCategoryTransaction() {
		return this.categoryTransaction;
	}

	public void setCategoryTransaction(CategoryTransaction categoryTransaction) {
		this.categoryTransaction = categoryTransaction;
	}

	@Override
	public SessionObject createSession(String title, String content,
			int categoryId) throws  CategoryNotFoundException,
			DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		return forumTransaction.createSession(requester, title, content,
				categoryTransaction.getCategory(requester, categoryId)).getSessionObjectWithMessage();
	}

	@Override
	public MessageObject followSession(String content, int sessionId)
			throws  DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Session sess = forumTransaction.getSession(requester, sessionId);
		return forumTransaction.followSession(requester, content, sess).getMessageObject(sess.getSessionObject());
	}

	@Override
	public Set<CategoryObject> getCategorySet() throws
			DatabaseException {
		Set<Category> categorySet = categoryTransaction.getCategorySet((User)this.getThreadLocalRequest().getSession().getAttribute("User"));
		Set<CategoryObject> categoryObjectSet = new LinkedHashSet<CategoryObject>();
		Iterator<Category> iterator = categorySet.iterator();
		while (iterator.hasNext()) {
			categoryObjectSet.add(iterator.next().getCategoryObjectTree(null));
		}
		return categoryObjectSet;
	}

	@Override
	public SessionObject getSessionDetail(int sessionId)
			throws  SessionNotFoundException,
			DatabaseException {
		return forumTransaction.getSession((User)this.getThreadLocalRequest().getSession().getAttribute("User"),sessionId).getSessionObjectWithMessage();
	}

	@Override
	public Set<SessionObject> getSessionSet() throws
			DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Set<Session> sessions = forumTransaction.getSessionSet(requester);
		Set<SessionObject> sessionObjects = new LinkedHashSet<SessionObject>();
		Iterator<Session> iterator = sessions.iterator();
		while (iterator.hasNext()) {
			sessionObjects.add(iterator.next().getSessionObject());
		}
		return sessionObjects;
	}

	@Override
	public Set<SessionObject> getSessionSet(int categoryId)
			throws  CategoryNotFoundException,
			DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Set<Session> sessions = null;
		sessions = forumTransaction.getSessionSet(requester,
				categoryTransaction.getCategory(requester, categoryId));
		Set<SessionObject> sessionObjects = new LinkedHashSet<SessionObject>();
		Iterator<Session> iterator = sessions.iterator();
		while (iterator.hasNext()) {
			sessionObjects.add(iterator.next().getSessionObject());
		}
		return sessionObjects;
	}

	@Override
	public void removeMessage(int messageId) throws
			MessageNotFoundException, DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Message message = forumTransaction.getMessage(requester, messageId);
		forumTransaction.removeMessage(requester, message);
	}

	@Override
	public void removeResource(int resourceId) throws
			ResourceNotFoundException, DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Resource resource = forumTransaction.getResource(requester, resourceId);
		forumTransaction.removeResource(requester, resource);
	}

	@Override
	public void removeResources(Set<Integer> resourceIdSet)
			throws  ResourceNotFoundException, DatabaseException {
		Iterator<Integer> iterator = resourceIdSet.iterator();
		while (iterator.hasNext()) {
			this.removeResource(iterator.next());
		}
	}

	@Override
	public void removeSession(int sessionId) throws
			PermissionDeniedException, DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Session session = forumTransaction.getSession(requester, sessionId);
		forumTransaction.removeSession(requester, session);
	}

	@Override
	public void updateMessage(String content, int messageId)
			throws  MessageNotFoundException,
			DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Message message = forumTransaction.getMessage(requester, messageId);
		message.setContent(content);
		forumTransaction.updateMessage(requester, message);
	}

	@Override
	public void updateTitle(String title, int sessionId)
			throws  SessionNotFoundException,
			DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Session session = forumTransaction.getSession(requester, sessionId);
		session.setTitle(title);
		forumTransaction.updateSession(requester, session);
	}

	@Override
	public Set<SessionObject> getSessionSetWithinCategory(int categoryId)
			throws CategoryNotFoundException, DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Set<Session> sessions = null;
		sessions = forumTransaction.getSessionSet(requester,

				categoryTransaction.getCategory(requester, categoryId)
				.getChildren());
		Set<SessionObject> sessionObjects = new LinkedHashSet<SessionObject>();
		Iterator<Session> iterator = sessions.iterator();
		while (iterator.hasNext()) {
			sessionObjects.add(iterator.next().getSessionObject());
		}
		return sessionObjects;
	}

	@Override
	public Set<SessionObject> getSessionSetKeywords(String keywords)
			throws DatabaseException {
		User requester = (User)this.getThreadLocalRequest().getSession().getAttribute("User");
		Set<Session> sessions = null;
		sessions = forumTransaction.getSessionSetByKeywords(requester, keywords.split("[ \t]"));
		Set<SessionObject> sessionObjects = new LinkedHashSet<SessionObject>();
		Iterator<Session> iterator = sessions.iterator();
		while (iterator.hasNext()) {
			sessionObjects.add(iterator.next().getSessionObject());
		}
		return sessionObjects;
	}

}
